﻿using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using InfoPathHelpers.Internal;

namespace InfoPathHelpers.Attachments
{
    public class PictureAttachmentEncoder
    {
        private const int MAX_IMAGE_WIDTH = 1152;
        private const int MAX_IMAGE_HEIGHT = 0;

        public static string EncodeFile(string fileName)
        {
            return EncodeFile(fileName, false);
        }

        public static string EncodeFile(string fileName, bool enableCompression)
        {
            string EncodedImage;

            // Load the image.
            Image InputImage = Bitmap.FromFile(fileName);
            ImageFormat OriginalFormat = InputImage.RawFormat;

            // If the image is wider than maximum reduce it's size.
            // This applies to all formats.
            if (InputImage.Width > MAX_IMAGE_WIDTH)
            {
                InputImage = InputImage.ReduceImageSize(MAX_IMAGE_WIDTH, MAX_IMAGE_HEIGHT);
            }

            // Reduce Jpeg images to 75% quality.
            if (OriginalFormat.Equals(ImageFormat.Jpeg) && enableCompression)
            {
                InputImage = InputImage.ReduceQuality(75);
            }
            // JPEGs are compressed, GIFs retain their format, everyting else is converted to PNG.
            else if(!OriginalFormat.Equals(ImageFormat.Gif))
            {
                InputImage.ChangeFormat(ImageFormat.Png);
            }

            EncodedImage = EncodeImage(InputImage);
            
            return EncodedImage;
        }

        public static void SaveImageData(string encodedImage, string outputFileName)
        {
            byte[] ImageData = Convert.FromBase64String(encodedImage);
            File.WriteAllBytes(outputFileName, ImageData);
        }

        public static void SaveImage(string encodedImage, string outputFileName)
        {
            Image OutputImage = DecodeImage(encodedImage);
            string ImageFormat = OutputImage.RawFormat.GetName();

            string OutputFileName = Path.Combine(Path.GetDirectoryName(outputFileName), 
                Path.GetFileNameWithoutExtension(outputFileName));
            OutputFileName += "." + ImageFormat;

            OutputImage.Save(OutputFileName, OutputImage.RawFormat);
            OutputImage.Dispose();
        }

        private static string EncodeImage(Image image)
        {
            ImageConverter Converter = new ImageConverter();
            byte[] ImageData = (byte[])Converter.ConvertTo(image, typeof(byte[]));
            string EncodedImage = Convert.ToBase64String(ImageData);
            return EncodedImage;
        }

        private static Image DecodeImage(string encodedImage)
        {
            byte[] ImageData = Convert.FromBase64String(encodedImage);
            ImageConverter Converter = new ImageConverter();
            Image Image = (Image)Converter.ConvertFrom(ImageData);
            return Image;
        }
    }
}
